<?php
namespace gnomephp\security;

use \gnomephp\doctrine\Doctrine,
\gnomephp\message\Message;

/**
 * Security class, if you want to create a authentication system this is the Controller to extend.
 * This Controller class lets you implement authentication to your application easily.
 *
 * CRUD stands for Create , Read , Update and Delete. Your entities can easily be managed with this manager.
 *
 * Override this Controller in your Application and you might want to override the __construct to have some security check implementation to check if the user is admin.
 *
 * @author peec
 *
 */
abstract class Security extends \gnomephp\mvc\CoreController{




	public function __construct(){
		parent::__construct();
		Doctrine::load();
		$this->lang->load('security', 'english');
	}

	const SECURITY_TOKEN = 'security.token';

	static public function getSessionModelPath(){
		return '\\'. GNOME_APP_NS . '\model\SecuritySession';
	}

	static public function getSessionModel($username){
		$ns = self::getSessionModelPath();
		return new $ns($username);
	}


	abstract protected function authenticate($username, $password);


	protected function getCurrentUserBySession(){
		$ns = Security::getSessionModelPath();
		if ($sess = $this->session->get(Security::SECURITY_TOKEN)){
			if ($current = $ns::getValidSession($sess, Security::getSessionModelPath())){
				return $current;
			}
		}
		return null;
	}

	/**
	 * Registers session for user if login is valid.
	 * Returns true on success validation of auth, false if not.
	 * @param string $username Username
	 * @param string $pw Password
	 */
	public function loginUser($username, $pw){
		if ($this->authenticate($username, $pw)){

			$session = Security::getSessionModel($username);
			$this->session->set(Security::SECURITY_TOKEN, $session->getSessionKey());



			Doctrine::getEM()->persist($session);

			Doctrine::getEM()->flush();

			$this->session->save();

			// Cleanup expiered sessions for this user.
			// This means that outdated sessions will be deleted from the storage engine.
			$ns = Security::getSessionModelPath();
			$ns::cleanupSessions($ns);
			return true;
		}
		return false;
	}

	public function login(){
		if ($this->getCurrentUserBySession() !== null){
			$this->redirect($this->view->url->linkTo('security_manage'));
		}
		if ($this->input->post){
			$post = $this->input->post->get();
			if ($this->loginUser($post['username'], $post['password'])){
				// Send message to flash
				Message::add(Message::SUCCESS, sprintf($this->lang->get('security')->get('success_login'), $post['username']));
				$this->redirectStateFirst($this->view->url->linkTo('security_manage'));
				
			}else{
				// Send message to flash
				Message::add(Message::ERROR, sprintf($this->lang->get('security')->get('fail_login'), $post['username']));
				
			}
		}

	}

	public function manage(){
		if ($user = $this->getCurrentUserBySession() == null){
			$this->redirect($this->view->url->linkTo('security_login'));
		}

		// $user = $this->getCurrentUserBySession();
		// echo "Hi {$user->getUsername()}!Welcome to the user panel.";

	}

	public function register(){
		if ($this->getCurrentUserBySession() !== null){
			$this->redirect($this->view->url->linkTo('security_manage'));
		}


	}

	public function logout(){
		if ($this->getCurrentUserBySession() == null){
			$this->redirect($this->view->url->linkTo('security_login'));
		}

		$ns = Security::getSessionModelPath();
		$ns::deleteSession($this->session->get(Security::SECURITY_TOKEN), $ns);

		$this->session->delete(Security::SECURITY_TOKEN);
		$this->session->save();

		// Send message to flash
		Message::add(Message::SUCCESS, $this->lang->get('security')->get('success_logout'));

		$this->redirectStateFirst($this->view->url->linkTo('security_login'));
		
		
		
	}
	
	
	
}
